package de.hauschild.orbitvm;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.JOptionPane;

import de.hauschild.orbitvm.controller.Controller;
import de.hauschild.orbitvm.controller.impl.HohmannController;
import de.hauschild.orbitvm.controller.impl.MeetAndGreetController;
import de.hauschild.orbitvm.visualization.VMFrame;
import de.hauschild.orbitvm.vm.VM;
import de.hauschild.orbitvm.vm.VMException;
import de.hauschild.orbitvm.vm.binary.BinaryLoader;

/**
 * The main entry point class.
 * 
 * @since 1.0.0
 * @author Hauschild
 */
public class Main {

  private static final int MAIN_PROBLEM = 1000;

  /**
   * The main entry point method. Use arguments in the form like:
   * <p>
   * <code>src/main/resources/binaries/bin2.obf 2001</code>
   * </p>
   * 
   * @param args
   *          the arguments
   * @throws FileNotFoundException
   *           the file not found exception
   * @throws IOException
   *           Signals that an I/O exception has occurred.
   */
  public static void main(final String[] args) throws FileNotFoundException, IOException {
    // get binary
    final String binary = args[0];
    // create loader
    final BinaryLoader loader = new BinaryLoader();
    // load binary
    loader.load(new DataInputStream(new FileInputStream(binary)));
    // create virtual machine
    final VM vm = new VM(loader.getMemory(), loader.getInstructions());
    // get configuration
    final int config = Integer.parseInt(args[1]);
    // set configuration
    vm.setConfiguration(config);
    // create vm visualization
    final VMFrame vmFrame = new VMFrame();
    // determine controller
    Controller controller = null;
    switch (config / MAIN_PROBLEM) {
      case 1 :
        controller = new HohmannController(vm, vmFrame);
        break;
      case 2 :
        controller = new MeetAndGreetController(vm, vmFrame);
        break;
      default :
        throw new IllegalArgumentException(String.format("No controller implemented for config %dxxx!", config
            / MAIN_PROBLEM));
    }
    // execute
    try {
      while (true) {
        // iterate
        controller.iterate();
      }
    } catch (final VMException vme) {
      if (vme.getMissionFailed()) {
        JOptionPane.showMessageDialog(vmFrame, vme.getMessage(), "Mission failed!", JOptionPane.ERROR_MESSAGE);
      } else {
        JOptionPane
            .showMessageDialog(vmFrame, vme.getMessage(), "Mission successful!", JOptionPane.INFORMATION_MESSAGE);
      }
    }
  }

  /**
   * Private constructor.
   */
  private Main() {
  }
}
